#include <sys_config.h>
#include <types.h>
#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <osal/osal.h>

#include <api/libosd/osd_lib.h>

#include "osdobjs_def.h"

#include "string.id"
#include "images.id"
#include "osd_config.h"
#include "osd_rsc.h"

#include "copper_common/system_data.h"
#include "copper_common/menu_api.h"
#include "win_com_menu_define.h"
#include "win_com.h"

/*******************************************************************************
*	Objects definition
*******************************************************************************/
extern CONTAINER win_osdset_con;

extern CONTAINER osd_item_con1;
extern CONTAINER osd_item_con2;
extern CONTAINER osd_item_con3;

extern TEXT_FIELD osd_item_txtname1;
extern TEXT_FIELD osd_item_txtname2;
extern TEXT_FIELD osd_item_txtname3;

extern TEXT_FIELD osd_item_txtset1;
extern TEXT_FIELD osd_item_txtset2;
extern TEXT_FIELD osd_item_txtset3;

extern TEXT_FIELD osd_item_line1;
extern TEXT_FIELD osd_item_line2;
extern TEXT_FIELD osd_item_line3;

static VACTION osd_item_con_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT osd_item_con_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

static VACTION osd_con_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT osd_con_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);


#define LDEF_CON(root, varCon,nxtObj,ID,IDl,IDr,IDu,IDd,l,t,w,h,conobj,focusID)		\
    DEF_CONTAINER(varCon,root,nxtObj,C_ATTR_ACTIVE,0, \
    ID,IDl,IDr,IDu,IDd, l,t,w,h, CON_SH_IDX,CON_HL_IDX,CON_SL_IDX,CON_GRY_IDX,   \
    osd_item_con_keymap,osd_item_con_callback,  \
    conobj, focusID,1)

#define LDEF_TXTNAME(root,varTxt,nxtObj,ID,IDl,IDr,IDu,IDd,l,t,w,h,resID,str)		\
    DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
    ID,IDl,IDr,IDu,IDd, l,t,w,h, TXTN_SH_IDX,TXTN_HL_IDX,TXTN_SL_IDX,TXTN_GRY_IDX,   \
    NULL,NULL,  \
    C_ALIGN_LEFT | C_ALIGN_VCENTER, 0,0,resID,str)

#define LDEF_TXTSET(root,varTxt,nxtObj,ID,IDl,IDr,IDu,IDd,l,t,w,h,resID,str)		\
    DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
    ID,IDl,IDr,IDu,IDd, l,t,w,h, TXTS_SH_IDX,TXTS_HL_IDX,TXTS_SL_IDX,TXTS_GRY_IDX,   \
    NULL,NULL,  \
    C_ALIGN_CENTER| C_ALIGN_VCENTER, 20,0,resID,str)


#define LDEF_MM_ITEM(root,varCon,nxtObj,varTxtName,varTxtset,varLine,ID,IDu,IDd,l,t,w,h,nameID,setstr)	\
	LDEF_CON(&root,varCon,nxtObj,ID,ID,ID,IDu,IDd,l,t,w,h,&varTxtName,1)	\
	LDEF_TXTNAME(&varCon,varTxtName,&varTxtset,0,0,0,0,0,l + TXTN_L_OF, t + TXTN_T_OF,TXTN_W,TXTN_H,nameID,NULL)	\
	LDEF_TXTSET(&varCon,varTxtset,NULL/*&varLine*/,1,1,1,1,1,l + TXTS_L_OF, t + TXTS_T_OF,TXTS_W,TXTS_H,0,setstr)\
	LDEF_LINE(&varCon,varLine,NULL,1,1,1,1,1,l + LINE_L_OF, t + LINE_T_OF,LINE_W,LINE_H,0,0)

LDEF_MM_ITEM(win_osdset_con,osd_item_con1, &osd_item_con2,osd_item_txtname1,osd_item_txtset1,osd_item_line1,1,3,2,	\
				CON_L, CON_T + (CON_H + CON_GAP)*0,CON_W,CON_H,	RS_SYSTEM_OSD_SETTING_SUBTITLE_DISPLAY,NULL)
LDEF_MM_ITEM(win_osdset_con,osd_item_con2, &osd_item_con3,osd_item_txtname2,  osd_item_txtset2,osd_item_line2,2,1,3,	\
				CON_L, CON_T + (CON_H + CON_GAP)*1,CON_W,CON_H,	RS_SYSTEM_OSD_SETTING_OSD_TIMEOUT,display_strs[0])
LDEF_MM_ITEM(win_osdset_con,osd_item_con3, NULL,osd_item_txtname3,osd_item_txtset3,osd_item_line3,3,2,1,	\
				CON_L, CON_T + (CON_H + CON_GAP)*2,CON_W,CON_H,	RS_SYSTEM_OSD_SETTING_OSD_TRANSPARENCY,display_strs[1])

DEF_CONTAINER(win_osdset_con,NULL,NULL,C_ATTR_ACTIVE,0, \
    1,0,0,0,0, W_L,W_T,W_W,W_H, WIN_SH_IDX,WIN_HL_IDX,WIN_SL_IDX,WIN_GRY_IDX,   \
    osd_con_keymap,osd_con_callback,  \
    (POBJECT_HEAD)&osd_item_con1, 1,0)


/*******************************************************************************
*	Local functions & variables define
*******************************************************************************/
CONTAINER* osd_items[] =
{
	&osd_item_con1,
	&osd_item_con2,
	&osd_item_con3,
};

POBJECT_HEAD osd_item_name[] =
{
	(POBJECT_HEAD)&osd_item_txtname1,
	(POBJECT_HEAD)&osd_item_txtname2,
	(POBJECT_HEAD)&osd_item_txtname3,
};

POBJECT_HEAD osd_item_set[] =
{
	(POBJECT_HEAD)&osd_item_txtset1,
	(POBJECT_HEAD)&osd_item_txtset2,
	(POBJECT_HEAD)&osd_item_txtset3,
};
#define MAX_OSD_TIMEOUT	10

void win_osd_set_subtitle_string(UINT8 input)
{
	if(input==0)
		OSD_SetTextFieldContent(&osd_item_txtset1, STRING_ID,RS_COMMON_OFF);				
	else
		OSD_SetTextFieldContent(&osd_item_txtset1, STRING_ID,RS_COMMON_ON);	
}

void win_osd_set_timeout_string(UINT8 input)
{
	UINT8 temp[5];
	sprintf(temp, "%d", input);
	ComAscStr2Uni(temp, display_strs[0]);
}

void win_osd_set_trans_string(UINT8 input)
{
	UINT8 temp[5];
	if(input)
	{
		sprintf(temp, "%d0%%", input);
		ComAscStr2Uni(temp, display_strs[1]);
	}
	else
	{
		sprintf(temp, "Off", input);
		ComAscStr2Uni(temp, display_strs[1]);
	}
}

/*******************************************************************************
*	key mapping and event callback definition
*******************************************************************************/

static VACTION osd_item_con_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	
	switch(key)
	{
	case V_KEY_RIGHT:
		act = VACT_INCREASE;
		break;		
	case V_KEY_LEFT:		
		act = VACT_DECREASE;
		break;		
	case V_KEY_ENTER:
		act = VACT_ENTER;
		break;		
	default:	
		act = VACT_PASS;
		break;
	}

	return act;

}

UINT8 win_osd_get_num()
{
	UINT8 ID=OSD_GetFocusID((POBJECT_HEAD)&win_osdset_con);
	SYSTEM_DATA* p_sys_data=sys_data_get();
	UINT8 num=0;
	
	switch(ID)
	{
		case MENU_OSD_TIMEOUT:
			num=MAX_OSD_TIMEOUT;
			break;
		case MENU_OSD_TRANSPARENCY:
			num=MAX_OSD_TRANSPARENCY+1;
			break;
	}
	return num;
}

PRESULT comlist_menu_osd_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	UINT16 i,wTop;
	UINT8 id;
	char str_len;
    	OBJLIST* ol;
	UINT8 temp[4];
	
	PRESULT cbRet = PROC_PASS;

    	ol = (OBJLIST*)pObj;
	
	if(event==EVN_PRE_DRAW)
	{
		id=OSD_GetFocusID((POBJECT_HEAD)&win_osdset_con);
		switch(id)
		{
			case MENU_OSD_TIMEOUT:
			    	wTop = OSD_GetObjListTop(ol);
			    	for(i=0;i<ol->wDep && (i+wTop)<ol->wCount;i++)
			    	{
					sprintf(temp,"%d", i+wTop+1);
					win_comlist_set_str(i + wTop,temp,NULL,0);
			    	}
				break;
			case MENU_OSD_TRANSPARENCY:
			    	wTop = OSD_GetObjListTop(ol);
			    	for(i=0;i<ol->wDep && (i+wTop)<ol->wCount;i++)
			    	{
					sprintf(temp,"%d0%%", i+wTop);
					if(i+wTop)
						win_comlist_set_str(i + wTop,temp,NULL,0);
					else
						win_comlist_set_str(i + wTop,NULL,NULL,RS_COMMON_OFF);
			    	}
				break;
		}
	}
	else if(event == EVN_POST_CHANGE)
		cbRet = PROC_LEAVE;

	return cbRet;
}

void win_osd_enter_key(POBJECT_HEAD pObj,UINT8 id)
{
	SYSTEM_DATA* p_sys_data=sys_data_get();
	OSD_RECT rect;
	COM_POP_LIST_PARAM_T param;
	
	rect.uLeft=CON_L+TXTS_L_OF;
	rect.uWidth=TXTS_W;
	rect.uHeight=250;
	param.selecttype = POP_LIST_SINGLESELECT;
	switch(id)
	{
		case MENU_OSD_TIMEOUT:
			#ifndef SD_UI
			rect.uHeight = 300;
			rect.uTop=CON_T + (CON_H + CON_GAP)*1;
			#else
			rect.uHeight = 250;
			rect.uTop=CON_T + (CON_H)*1;
			#endif
			
			param.cur=p_sys_data->osd_set.time_out-1;
			p_sys_data->osd_set.time_out = win_com_open_sub_list(POP_LIST_MENU_OSDSET,&rect,&param)+1;
			win_osd_set_timeout_string(p_sys_data->osd_set.time_out);
			OSD_TrackObject(pObj,C_UPDATE_ALL);
			break;
		case MENU_OSD_TRANSPARENCY:
			#ifndef SD_UI
			rect.uHeight = 300;
			rect.uTop=CON_T + (CON_H + CON_GAP)*2;
			#else
			rect.uHeight = 250;
			rect.uTop=CON_T + (CON_H + CON_GAP)*1 + CON_H;
			#endif
			
			param.cur=p_sys_data->osd_set.osd_trans;
			p_sys_data->osd_set.osd_trans = win_com_open_sub_list(POP_LIST_MENU_OSDSET,&rect,&param);
			win_osd_set_trans_string(p_sys_data->osd_set.osd_trans);
			OSD_TrackObject(pObj,C_UPDATE_ALL);
			sys_data_set_palette(0);
			break;
	}
}

void win_osd_left_key(POBJECT_HEAD pObj,UINT8 id)
{
	SYSTEM_DATA* p_sys_data=sys_data_get();
	switch(id)
	{
		case MENU_OSD_SUB_DISPLAY:
			if(p_sys_data->osd_set.subtitle_display==0)
			{
				p_sys_data->osd_set.subtitle_display=1;
			}
			else
			{
				p_sys_data->osd_set.subtitle_display--;
			}
			win_osd_set_subtitle_string(p_sys_data->osd_set.subtitle_display);
			OSD_TrackObject(pObj,C_UPDATE_ALL);
			break;
		case MENU_OSD_TIMEOUT:
			if(p_sys_data->osd_set.time_out==1)
			{
				p_sys_data->osd_set.time_out=MAX_OSD_TIMEOUT;
			}
			else
			{
				p_sys_data->osd_set.time_out--;
			}
			win_osd_set_timeout_string(p_sys_data->osd_set.time_out);
			OSD_TrackObject(pObj,C_UPDATE_ALL);
			break;
		case MENU_OSD_TRANSPARENCY:
			if(p_sys_data->osd_set.osd_trans==0)
			{
				p_sys_data->osd_set.osd_trans=MAX_OSD_TRANSPARENCY;
			}
			else
			{
				p_sys_data->osd_set.osd_trans--;
			}
			win_osd_set_trans_string(p_sys_data->osd_set.osd_trans);
			OSD_TrackObject(pObj,C_UPDATE_ALL);
			sys_data_set_palette(0);
			break;
	}
}

void win_osd_right_key(POBJECT_HEAD pObj,UINT8 id)
{
	SYSTEM_DATA* p_sys_data=sys_data_get();
	switch(id)
	{
		case MENU_OSD_SUB_DISPLAY:
			if(p_sys_data->osd_set.subtitle_display==1)
			{
				p_sys_data->osd_set.subtitle_display=0;
			}
			else
			{
				p_sys_data->osd_set.subtitle_display++;
			}
			win_osd_set_subtitle_string(p_sys_data->osd_set.subtitle_display);
			OSD_TrackObject(pObj,C_UPDATE_ALL);
			break;
		case MENU_OSD_TIMEOUT:
			if(p_sys_data->osd_set.time_out==MAX_OSD_TIMEOUT)
			{
				p_sys_data->osd_set.time_out=1;
			}
			else
			{
				p_sys_data->osd_set.time_out++;
			}
			win_osd_set_timeout_string(p_sys_data->osd_set.time_out);
			OSD_TrackObject(pObj,C_UPDATE_ALL);
			break;
		case MENU_OSD_TRANSPARENCY:
			if(p_sys_data->osd_set.osd_trans==MAX_OSD_TRANSPARENCY)
			{
				p_sys_data->osd_set.osd_trans=0;
			}
			else
			{
				p_sys_data->osd_set.osd_trans++;
			}
			win_osd_set_trans_string(p_sys_data->osd_set.osd_trans);
			OSD_TrackObject(pObj,C_UPDATE_ALL);
			sys_data_set_palette(0);
			break;
	}
}

static PRESULT osd_item_con_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	UINT8	unact,input;
	UINT8	id = OSD_GetObjID(pObj);
	SYSTEM_DATA* p_sys_data=sys_data_get();

	switch(event)
	{		
	case EVN_FOCUS_PRE_GET:
		break;
		
	case EVN_FOCUS_PRE_LOSE:
		break;

	case EVN_UNKNOWN_ACTION:
		unact = (VACTION)(param1>>16) ;
		if(unact == VACT_ENTER)
		{
			win_osd_enter_key(pObj,id);
		}
		else if(unact == VACT_DECREASE)
		{
			win_osd_left_key(pObj,id);
		}
		else if(unact == VACT_INCREASE)
		{
			win_osd_right_key(pObj,id);
		}
		ret = PROC_LOOP;
		break;
	}
	return ret;

}

static VACTION osd_con_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	
	switch(key)
	{
	case V_KEY_UP:
		act = VACT_CURSOR_UP;
		break;
		
	case V_KEY_DOWN:
		act = VACT_CURSOR_DOWN;
		break;		
		
	case V_KEY_EXIT:
	case V_KEY_MENU:
		act = VACT_CLOSE;
		break;
		
	case V_KEY_ENTER:
		act = VACT_ENTER;
		break;

	default:	
		act = VACT_PASS;
		break;
	}

	return act;
}

static PRESULT osd_con_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{
	PRESULT ret = PROC_PASS;
	UINT8	unact;
	UINT32 i;
	BOOL subt_flag;
	CONTAINER* cont = (CONTAINER*)pObj;
	UINT8	id = OSD_GetObjID(pObj);
	SYSTEM_DATA* p_sys_data;
	
	switch(event)
	{
	case EVN_PRE_OPEN:
#ifdef SUPPORT_POP_SUBT
		subt_flag = TRUE;
#else
		subt_flag = FALSE;
#endif
		wincom_open_title((POBJECT_HEAD)&win_osdset_con,RS_SYSTEM_OSD_SETTING, 0);
		if(subt_flag)
		{
			remove_menu_item((CONTAINER *) pObj,(POBJECT_HEAD)&osd_item_con1,(CON_H + CON_GAP));
		}

		p_sys_data=sys_data_get();
		if(p_sys_data->osd_set.subtitle_display == 0)
			p_sys_data->osd_set.subtitle_lang = 0xFF;/*If subtitle off,clear set_sub_lang_idx*/
		win_osd_set_subtitle_string(p_sys_data->osd_set.subtitle_display);
		win_osd_set_timeout_string(p_sys_data->osd_set.time_out);
		win_osd_set_trans_string(p_sys_data->osd_set.osd_trans);
		break;
	
	case EVN_POST_OPEN:
		break;
		
	case EVN_PRE_CLOSE:
		p_sys_data=sys_data_get();
		if(p_sys_data->osd_set.subtitle_display == 0)	
			p_sys_data->osd_set.subtitle_lang = 0xFF;/*If subtitle off,clear set_sub_lang_idx*/
		
		sys_data_save(1);
		/* Make OSD not flickering */
		*((UINT32*)param2) &= ~C_CLOSE_CLRBACK_FLG;	
		break;

	case EVN_POST_CLOSE:
		break;
	}
	return ret;
}

